/**
 * 作者: wgx
 * 日期: 2024-10-14 16:33:42
 * 备注: 势力
 */
package com.motu.monstercity.server.game.userdata;

import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.server.game.base.CommonUtils;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.act.ActTopRanking;
import com.motu.monstercity.server.game.commondata.build.BuildMain;
import com.motu.monstercity.server.game.commondata.maintask.MainTaskConstant;
import com.motu.monstercity.server.game.commondata.partner.PartnerMain;
import com.motu.monstercity.server.game.commondata.rank.RankConstant;
import com.motu.monstercity.server.game.commondata.world.WorldRadar;
import com.motu.monstercity.server.game.logic.*;
import com.motu.vertx.module.utility.model.EntityManager;
import com.motu.vertx.module.utility.model.Model;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.json.JsonArray;

import java.util.ArrayList;
import java.util.List;

public class UserPower extends UserPowerModel {
    public UserPower() {
        super();
    }

    public void reset() {
        if (Tool.isEmpty(getPowerAddUnionCv())) {
            putPowerAddUnionCv(SkillManager.createSkillEffectArray().toString());
            update();
        }
    }

    // 更新power 这个字段的值, 收益相关字段先不更新，解锁秘书有加战力，也有加城市收益
    public void updatePower(PBUserData.Builder pbUserData, UserInfo userInfo, long newPower) {
        if (newPower == getPower()) {
            return;
        }
        super.putPower(newPower);
        if (newPower > getMaxPower()) {
            super.putMaxPower(newPower);
            MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_143, newPower);// 更新主线任务,成就,日常任务的进度
            MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_257, newPower - getMaxPower());// 更新主线任务,成就,日常任务的进度
            RankActManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_143, newPower);
            userInfo.putMaxPower(newPower);
            userInfo.update();// 更新userinfo 的最高战力字段
            MainTaskManager.updateServerHonor(pbUserData, userInfo, MainTaskConstant.HONOR_TYPE_1, newPower);// 更新全服成就进度
            RankManager.updateRank(RankConstant.SERVER_RANK_POWER, userInfo.getServerId(), getId(), newPower, "0");// 更新战力排行榜
        }
    }

    // 玩家的战力发生变化，基础战力变化，或是加成有变化，全量更新总战力
    public void handlePowerChange(PBUserData.Builder pbUserData, UserInfo userInfo, long newPower) {
        updatePower(pbUserData, userInfo, newPower);
        // 战力更新,商业建筑的每秒收益也会跟着更新,重新下发给客户端
        List<UserBuild> userBuildList = takeUserBuildList(0);// 所有的商业建筑
        BuildManager.batchUpdateBuildEarn(pbUserData, userInfo, this, userBuildList);
    }

    // 处理总收益有变化逻辑 更新总收益 总收益=（建筑收益+后代收益）*（1+特权卡收益加成+兽潮收益）
    public void handleEarnChange(PBUserData.Builder pbUserData, UserInfo userInfo) {
        long totalEarn = countCurrentEarn();//总收益=（建筑收益+后代收益）*（1+特权卡收益加成+永久收益加成）
        super.putEarn(totalEarn);
        long oldMaxEarn = getMaxEarn();
        if (totalEarn > getMaxEarn()) {// 在排行榜、等计算时，使用的都是历史最高总收益
            super.putMaxEarn(totalEarn);
            MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_184, totalEarn);// 更新主线任务,成就,日常任务的进度
            MainTaskManager.updateServerHonor(pbUserData, userInfo, MainTaskConstant.HONOR_TYPE_2, totalEarn);// 更新全服成就进度
            RankActManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_184, totalEarn);
            RankManager.updateRank(RankConstant.SERVER_RANK_EARN, userInfo.getServerId(), getId(), totalEarn, "0");// 更新收益排行榜
            RankActManager.addUserrank(userInfo.getServerId(), ActTopRanking.RANK_TYPE_EARN, userInfo, totalEarn, false); // 更新本服冲榜
            RankActManager.addUserCrossRank(userInfo, userInfo.getServerId(), ActTopRanking.RANK_TYPE_EARN, totalEarn, false); // 更新跨服冲榜
            UnionManager.updateUnionEarnRankByLock(userInfo,totalEarn - oldMaxEarn);//更新联盟总收益
        }
        update();
        ProtoDataUtils.updatePBUserData(pbUserData, this);
    }

    // 全量更新大世界模块战力加成固定值
    public void updatePowerAddWorldCv(PBUserData.Builder pbUserData, UserInfo userInfo, UserBuild userBuild) {
        if (userBuild == null || !userBuild.isRadarBuild()) {
            return;// 不是雷达
        }
        int newValue = userBuild.takeRadarAdd();
        if (newValue == getPowerAddWorldCv()) {
            return;// 没变化
        }
        super.putPowerAddWorldCv(newValue);
        List<UserPartner> partnerList = takeUserPartnerList(0);// 影响所有干员
        long addPowerTotal = 0L;
        for (UserPartner userPartner : partnerList) {
            addPowerTotal += userPartner.reCountPower(userInfo, this);
            userPartner.update();
            ProtoDataUtils.updatePBUserData(pbUserData, userPartner);
        }
        long newPower = getPower() + addPowerTotal;
        handlePowerChange(pbUserData, userInfo, newPower);
    }

    // 增量更新建筑的总收益
    public void addBuildEarn(PBUserData.Builder pbUserData, UserInfo userInfo, long addBuildEarn) {
        if (addBuildEarn == 0) {
            return;
        }
        super.addBuildEarn(addBuildEarn);
        handleEarnChange(pbUserData, userInfo);// 更新总收益 总收益=（建筑收益+后代收益）*（1+特权卡收益加成+永久收益加成）
    }

    // 增量更新子嗣的总收益
    public void addChildEarn(PBUserData.Builder pbUserData, UserInfo userInfo, long addChildEarn) {
        if (addChildEarn == 0) {
            return;
        }
        super.addChildEarn(addChildEarn);
        handleEarnChange(pbUserData, userInfo);// 更新总收益 总收益=（建筑收益+后代收益）*（1+特权卡收益加成+永久收益加成）

        RankManager.updateRank(RankConstant.SERVER_RANK_CHILD, userInfo.getServerId(), userInfo.getId(), getChildEarn(), "0");
        RankActManager.addUserrank(userInfo.getServerId(), ActTopRanking.RANK_TYPE_CHILD_EARN, userInfo, getChildEarn(), false);
        RankActManager.addUserCrossRank(userInfo, userInfo.getServerId(), ActTopRanking.RANK_TYPE_CHILD_EARN, getChildEarn(), false);
    }

    // 全量更新兽潮的收益加成
    public void updateEarnAddMonster(PBUserData.Builder pbUserData, UserInfo userInfo, int newValue) {
        if (newValue == getEarnAddMonsterPer()) {
            return;
        }
        super.putEarnAddMonsterPer(newValue);
        handleEarnChange(pbUserData, userInfo);// 更新总收益 总收益=（建筑收益+后代收益）*（1+特权卡收益加成+永久收益加成）
    }

    // 更新特权卡加成, 全量更新
    public void updateEarnAddPricard(PBUserData.Builder pbUserData, UserInfo userInfo) {
        int totalAdd = IapManager.takePrivilegeValueByType(userInfo.getId(), "earn_num");// 特权卡的加成 500 表示加成5%
        if (totalAdd == getPricardAdd()) {
            return;
        }
        super.putPricardAdd(totalAdd);// 500表示加成5%
        handleEarnChange(pbUserData, userInfo);// 更新总收益 总收益=（建筑收益+后代收益）*（1+特权卡收益加成+永久收益加成）
    }

    // 更新怪兽洞窟的加成, 全量更新
    public void updateEarnAddCave(PBUserData.Builder pbUserData, UserInfo userInfo, int addValue) {
        if (addValue == getEarnAddCavePer()) {
            return;
        }
        super.putEarnAddCavePer(addValue);// 500表示加成5%
        handleEarnChange(pbUserData, userInfo);// 更新总收益 总收益=（建筑收益+后代收益）*（1+特权卡收益加成+永久收益加成）
    }

    /**
     * 增量更新 秘书技能加成的百分比，会有多个秘书技能生效，addvalue可能是负数
     * @param pbUserData
     * @param userInfo
     * @param skillId 技能id
     * @param diffValue 变动的值可能是负数
     */
    public void updateEarnAddSecr(PBUserData.Builder pbUserData, UserInfo userInfo, int skillId, int diffValue) {
        if (diffValue == 0) {
            return;
        }
        // todo
        handleEarnChange(pbUserData, userInfo);// 更新总收益 总收益=（建筑收益+后代收益）*（1+特权卡收益加成+永久收益加成）
    }



    // 当前收益的总收益  总收益=（建筑收益+后代收益）*（1+特权卡收益加成+兽潮加成）
    public long countCurrentEarn() {
        double baseEarn = getBuildEarn() + getChildEarn();
        double totalEarn = baseEarn * (10000 + getPricardAdd() + getEarnAddMonsterPer()) / 10000;
        return (long) totalEarn;
    }

    // 总的加成 百分比 统一放大1W倍,目前有称号，联盟地标，光环技能
    public int takeTotalAddPer(UserPartner userPartner) {
        int total = 0;
        total += getPowerAddTitlePer();// 称号对所有干员都有效
        total += SkillManager.countAddByCharacterType(userPartner.getCharacterType(), getPowerAddUnionPerArray());// 联盟地标
        total += SkillManager.countAddByCharacterType(userPartner.getCharacterType(), getPowerAddHaloPerArray());// 光环技能

        return total;
    }


    // 总的加成 固定值，目前只有大世界模块的雷达
    public int takeTotalAddCv(int partnerId) {
        int total = 0;
        total += getPowerAddWorldCv();// 雷达对所有干员都有效
        total += getPowerAddTitleCv();// 称号加战力 固定值

        total += getPowerUnionCv(partnerId);
        return total;
    }

    /**
     * 获取联盟对干员战力加成的固定值
     * @param partnerId
     * @return
     */
    private int getPowerUnionCv(int partnerId) {
        // 联盟地标建筑 对干员战力加成
        int total = 0;
        JsonArray powerAddUnionCvArray = getPowerAddUnionCvArray();
        // 1. 提取基础值并校验数组非空
        if (powerAddUnionCvArray != null && !powerAddUnionCvArray.isEmpty()) {
            // 2. 所有干员的固定加成 (索引0)
            total += powerAddUnionCvArray.getInteger(0);
            // 3. 获取伙伴数据
            PartnerMain partnerMain = PartnerManager.getPartnerMain(partnerId);
            if (partnerMain != null) {
                int characterType = partnerMain.getCharacterType();

                // 4. 校验性格索引有效性（避免越界）
                if (characterType > 0 && characterType < powerAddUnionCvArray.size()) {
                    // 5. 追加对应性格干员的加成
                    total += powerAddUnionCvArray.getInteger(characterType);
                } else {
                    logger.warn("Invalid characterType index: {} for partnerId: {}", characterType, partnerId);
                }
            }
        }
        return total;
    }

    /**
     * 获取已经解锁的某性格的所有干员id
     * @param charType 0表示全部
     * @return
     */
    public JsonArray takePartnerIds(int charType) {
        JsonArray jsonArray = getPartnerIdArray();
        if (charType == 0) {
            return jsonArray;
        }
        JsonArray result = new JsonArray();
        for (int i=0; i<jsonArray.size(); i++) {
            int partnerId = jsonArray.getInteger(i);
            PartnerMain partnerMain = PartnerManager.getPartnerMain(partnerId);
            if (partnerMain != null && partnerMain.getCharacterType() == charType) {
                result.add(partnerId);
            }
        }
        return result;
    }

    // 获取已经解锁的某性格的所有干员 userpartner
    public List<UserPartner> takeUserPartnerList(int charType) {
        List<UserPartner> list = new ArrayList<>();
        JsonArray partnerIds = takePartnerIds(charType);
        for (Model model : EntityManager.getEntityList(UserPartner.class, getId(), partnerIds)) {
            UserPartner entity = (UserPartner) model;
            list.add(entity);
        }
        return list;
    }

    /**
     * 获取已经解锁的某性格的所有商业建筑id
     * @param charType 0表示全部
     * @return
     */
    public JsonArray takeBuildIds(int charType) {
        JsonArray jsonArray = getBuildIdArray();
        if (charType == 0) {
            return jsonArray;
        }
        JsonArray result = new JsonArray();
        for (int i=0; i<jsonArray.size(); i++) {
            int buildId = jsonArray.getInteger(i);
            BuildMain buildMain = BuildManager.getBuildMain(buildId);
            if (buildMain != null && buildMain.isBusinessBuild() && buildMain.getCharacterType() == charType) {
                result.add(buildId);
            }
        }
        return result;
    }

    // 获取已经解锁的某性格的所有商业建筑 userbuild
    public List<UserBuild> takeUserBuildList(int charType) {
        List<UserBuild> list = new ArrayList<>();
        JsonArray buildIdS = takeBuildIds(charType);
        for (Model model : EntityManager.getEntityList(UserBuild.class, getId(), buildIdS)) {
            UserBuild entity = (UserBuild) model;
            list.add(entity);
        }
        return list;
    }

    //  增加一个干员id
    public void addPartnerId(int parnerMainId) {
        JsonArray jsonArray = getPartnerIdArray();
        if (!Tool.isInList(jsonArray, parnerMainId)) {
            jsonArray.add(parnerMainId);
            putPartnerId(jsonArray.toString());
        }
    }

    //  增加一个建筑id
    public void addBuildId(int buildMainId) {
        JsonArray jsonArray = getBuildIdArray();
        if (!Tool.isInList(jsonArray, buildMainId)) {
            jsonArray.add(buildMainId);
            putBuildId(jsonArray.toString());
        }
    }

    // 增量更新秘书经营技能的加成
    public void updateEarnSecrPer(int charType, int addValue) {
        JsonArray jsonArray = getEarnAddSecrPerArray();
        if (jsonArray == null || jsonArray.size() == 0) {
            return;
        }
        int newValue = jsonArray.getInteger(charType) + addValue;
        jsonArray.set(charType, newValue);
        putEarnAddSecrPer(jsonArray.toString());
    }
}
